﻿using System;

namespace WindowsFormsApplication1
{
    /// <summary>
    /// 抽象类测试
    /// </summary>
    public abstract class AbstractClass
    {
        /// <summary>
        /// 基类定义的字符串
        /// </summary>
        protected string New_String = "这是在基类定义的一个字符串";

        /// <summary>
        /// 本数在100以内时该对象是不和任意其他相同对象相等的
        /// </summary>
        public int CAN_EQ = 5;

        /// <summary>
        /// 共有静态字段
        /// </summary>
        public static int TYPE_MIN = 2;

        /// <summary>
        /// 内部常量，测试发现静态变量也是不能作为case条件的
        /// </summary>
        private const int TYPE_1 = 1;

        private const int TYPE_2 = 2;

        private const int TYPE_3 = 3;

        /// <summary>
        /// 获取两个值最大的一个
        /// </summary>
        /// <param name="p_one">第一个值</param>
        /// <param name="p_two">第二个值</param>
        /// <returns></returns>
        private int getMax(int p_one, int p_two)
        {
            if (p_one >= p_two)
            {
                return p_one;
            }
            else
            {
                return p_two;
            }
        }

        /// <summary>
        /// 抽象类中也可以有非抽象方法,还可以被继承
        /// </summary>
        /// <param name="p_one"></param>
        /// <param name="p_two"></param>
        /// <returns></returns>
        public virtual int getMin(int p_one, int p_two)
        {
            if (p_one >= p_two)
            {
                return p_two;
            }
            else
            {
                return p_one;
            }
        }

        public int getOne(int p_type, int p_one, int p_two)
        {
            int t_out;
            switch (p_type)
            {
                case TYPE_1:
                    t_out = this.getMax(p_one, p_two);
                    break;
                case TYPE_2:
                    t_out = this.getMin(p_one, p_two);
                    break;
                case TYPE_3:
                    bool t_eq = this.isEq(1, 2);
                    if (t_eq)
                    {
                        t_out = 22;
                    }
                    else
                    {
                        t_out = 11;
                    }
                    break;
                default:
                    t_out = 0;
                    //default也是需要break
                    break;

            }
            return t_out;
        }

        /// <summary>
        /// 判断两数是否相等，抽象方法是没有函数体的
        /// </summary>
        /// <param name="p_one">第一个数</param>
        /// <param name="p_two">第二个数</param>
        /// <returns>相等返回TRUE，否则返回FALSE</returns>
        public abstract bool isEq(int p_one, int p_two);

        public virtual int getHandMU()
        {
            return 0;
        }
    }

    /// <summary>
    /// 测试继承
    /// </summary>
    class CanobjClass : AbstractClass
    {
        /// <summary>
        /// 显示隐藏基类的相同定义
        /// </summary>
        public new string New_String = "基类也定义了这个变量，但继承类可以覆盖";

        /// <summary>
        /// 复写实现基类的虚拟方法
        /// </summary>
        /// <param name="p_one"></param>
        /// <param name="p_two"></param>
        /// <returns></returns>
        public override bool isEq(int p_one, int p_two)
        {
            if (p_one == p_two)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 覆盖了基类的virtual调用，使用base访问基类
        /// </summary>
        /// <param name="p_one"></param>
        /// <param name="p_two"></param>
        /// <returns></returns>
        public override int getMin(int p_one, int p_two)
        {
            return base.getMin(p_one, p_two) + 100;
        }
    }

    /// <summary>
    /// 定义一个封装类，不允许被继承
    /// </summary>
    public sealed class SealedClass : AbstractClass
    {
        /// <summary>
        /// 测试重写
        /// </summary>
        /// <param name="p_one">第一个数</param>
        /// <param name="p_two">第二个数</param>
        /// <returns></returns>
        public override bool isEq(int p_one, int p_two)
        {
            return false;
        }

        /// <summary>
        /// 需重写Equals，否则会产生警告
        /// </summary>
        /// <param name="obj">要比较的对象</param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        /// <summary>
        /// 需重写GetHashCode，否则会产生警告
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        
        /// <summary>
        /// 重定义运算符==
        /// </summary>
        /// <param name="p_one">第一个对象</param>
        /// <param name="p_two">第二个对象</param>
        /// <returns></returns>
        public static bool operator ==(SealedClass p_one, SealedClass p_two)
        {
            if (p_one.CAN_EQ == p_two.CAN_EQ)
            {
                if (p_one.CAN_EQ > 100)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// ==和!=是一对运算符，所以也必须定义!=
        /// </summary>
        /// <param name="p_one">第一个对象</param>
        /// <param name="p_two">第二个对象</param>
        /// <returns></returns>
        public static bool operator !=(SealedClass p_one, SealedClass p_two)
        {
            if (p_one.CAN_EQ == p_two.CAN_EQ && p_one.CAN_EQ > 100)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 测试运算符
        /// </summary>
        /// <param name="p_one">第一个对象</param>
        /// <param name="p_two">第二个对象</param>
        /// <returns></returns>
        public static bool isHeq(SealedClass p_one, SealedClass p_two)
        {
            return p_one == p_two;
        }

        /// <summary>
        /// sealed是不能和virtual共存的，他们是相反的意思
        /// </summary>
        /// <returns></returns>
        public override sealed int getHandMU()
        {
            return 411370875;
        }
    }
}
